﻿using System;


namespace advadev.CanOpen
{

    /// <summary>
    /// Represents a can open message
    /// </summary>
    sealed public class CanOpenMessage
    {

        /// <summary>for internal use</summary>
        private byte _byte0 = 0;
        /// <summary>for internal use</summary>
        private byte _byte1 = 0;
        /// <summary>for internal use</summary>
        private byte _byte2 = 0;
        /// <summary>for internal use</summary>
        private byte _byte3 = 0;
        /// <summary>for internal use</summary>
        private byte _byte4 = 0;
        /// <summary>for internal use</summary>
        private byte _byte5 = 0;
        /// <summary>for internal use</summary>
        private byte _byte6 = 0;
        /// <summary>for internal use</summary>
        private byte _byte7 = 0;


        /// <summary>
        /// Creates a new can open massage
        /// </summary>
        /// <param name="canId">
        /// CAN-ID
        /// </param>
        /// <param name="byte0">
        /// Byte 0
        /// </param>
        /// <param name="byte1">
        /// Byte 1
        /// </param>
        /// <param name="byte2">
        /// Byte 2
        /// </param>
        /// <param name="byte3">
        /// Byte 3
        /// </param>
        /// <param name="byte4">
        /// Byte 4
        /// </param>
        /// <param name="byte5">
        /// Byte 5
        /// </param>
        /// <param name="byte6">
        /// Byte 6
        /// </param>
        /// <param name="byte7">
        /// Byte 7
        /// </param>
        public CanOpenMessage(UInt16 canId, byte byte0, byte byte1, byte byte2, byte byte3, byte byte4, byte byte5, byte byte6, byte byte7)
            : this(canId, byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7, 8, false)
        {
        }

        /// <summary>
        /// Creates a new can open massage
        /// </summary>
        /// <param name="canId">
        /// CAN-ID
        /// </param>
        /// <param name="byte0">
        /// Byte 0
        /// </param>
        /// <param name="byte1">
        /// Byte 1
        /// </param>
        /// <param name="byte2">
        /// Byte 2
        /// </param>
        /// <param name="byte3">
        /// Byte 3
        /// </param>
        /// <param name="byte4">
        /// Byte 4
        /// </param>
        /// <param name="byte5">
        /// Byte 5
        /// </param>
        /// <param name="byte6">
        /// Byte 6
        /// </param>
        /// <param name="byte7">
        /// Byte 7
        /// </param>
        /// <param name="length">
        /// Length of the can open message (max. is 8)
        /// </param>
        public CanOpenMessage(UInt16 canId, byte byte0, byte byte1, byte byte2, byte byte3, byte byte4, byte byte5, byte byte6, byte byte7, uint length)
            : this(canId, byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7, length, false)
        {
        }

        /// <summary>
        /// Creates a new can open massage
        /// </summary>
        /// <param name="canId">
        /// CAN-ID
        /// </param>
        /// <param name="byte0">
        /// Byte 0
        /// </param>
        /// <param name="byte1">
        /// Byte 1
        /// </param>
        /// <param name="byte2">
        /// Byte 2
        /// </param>
        /// <param name="byte3">
        /// Byte 3
        /// </param>
        /// <param name="byte4">
        /// Byte 4
        /// </param>
        /// <param name="byte5">
        /// Byte 5
        /// </param>
        /// <param name="byte6">
        /// Byte 6
        /// </param>
        /// <param name="byte7">
        /// Byte 7
        /// </param>
        /// <param name="length">
        /// Length of the can open message (max. is 8)
        /// </param>
        /// <param name="isRemoteTransmissionRequest">
        /// Flag indicating whether this is a remote transmission request
        /// </param>
        public CanOpenMessage(UInt16 canId, byte byte0, byte byte1, byte byte2, byte byte3, byte byte4, byte byte5, byte byte6, byte byte7, uint length, bool isRemoteTransmissionRequest)
        {
            CanId = canId;
            Byte0 = byte0;
            Byte1 = byte1;
            Byte2 = byte2;
            Byte3 = byte3;
            Byte4 = byte4;
            Byte5 = byte5;
            Byte6 = byte6;
            Byte7 = byte7;
            Length = Math.Min(length, 8);
            IsRemoteTransmissionRequest = isRemoteTransmissionRequest;
        }


        /// <summary>
        /// Gets or sets a flag indicating whether this is a remote transmission
        /// request
        /// </summary>
        public bool IsRemoteTransmissionRequest
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the CAN-ID
        /// </summary>
        public UInt16 CanId
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the byte 0
        /// </summary>
        public byte Byte0
        {
            get
            {
                return (Length > 0 ? _byte0 : (byte)0);
            }
            set
            {
                _byte0 = value;
            }
        }

        /// <summary>
        /// Gets or sets the byte 1
        /// </summary>
        public byte Byte1
        {
            get
            {
                return (Length > 1 ? _byte1 : (byte)0);
            }
            set
            {
                _byte1 = value;
            }
        }

        /// <summary>
        /// Gets or sets the byte 2
        /// </summary>
        public byte Byte2
        {
            get
            {
                return (Length > 2 ? _byte2 : (byte)0);
            }
            set
            {
                _byte2 = value;
            }
        }

        /// <summary>
        /// Gets or sets the byte 3
        /// </summary>
        public byte Byte3
        {
            get
            {
                return (Length > 3 ? _byte3 : (byte)0);
            }
            set
            {
                _byte3 = value;
            }
        }

        /// <summary>
        /// Gets or sets the byte 4
        /// </summary>
        public byte Byte4
        {
            get
            {
                return (Length > 4 ? _byte4 : (byte)0);
            }
            set
            {
                _byte4 = value;
            }
        }

        /// <summary>
        /// Gets or sets the byte 5
        /// </summary>
        public byte Byte5
        {
            get
            {
                return (Length > 5 ? _byte5 : (byte)0);
            }
            set
            {
                _byte5 = value;
            }
        }

        /// <summary>
        /// Gets or sets the byte 6
        /// </summary>
        public byte Byte6
        {
            get
            {
                return (Length > 6 ? _byte6 : (byte)0);
            }
            set
            {
                _byte6 = value;
            }
        }

        /// <summary>
        /// Gets or sets the byte 7
        /// </summary>
        public byte Byte7
        {
            get
            {
                return (Length > 7 ? _byte7 : (byte)0);
            }
            set
            {
                _byte7 = value;
            }
        }

        /// <summary>
        /// Gets or sets the length of the can open message (max. is 8)
        /// </summary>
        public uint Length
        {
            get;
            set;
        }


        #region base implementation
        override public string ToString()
        {
            string result = string.Format("0x{0:X3}", CanId);
            if (Length > 0)
            {
                result += string.Format(" {0:X2}", Byte0);
            }
            if (Length > 1)
            {
                result += string.Format(" {0:X2}", Byte1);
            }
            if (Length > 2)
            {
                result += string.Format(" {0:X2}", Byte2);
            }
            if (Length > 3)
            {
                result += string.Format(" {0:X2}", Byte3);
            }
            if (Length > 4)
            {
                result += string.Format(" {0:X2}", Byte4);
            }
            if (Length > 5)
            {
                result += string.Format(" {0:X2}", Byte5);
            }
            if (Length > 6)
            {
                result += string.Format(" {0:X2}", Byte6);
            }
            if (Length > 7)
            {
                result += string.Format(" {0:X2}", Byte7);
            }
            return result;
        }
        #endregion base implementation

    }

}
